using System;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;

namespace ShadeTree.Binding.Drivers
{
    public class WinFormsControlDriver : IControlDriver
    {
        private readonly Control _control;
        private ToolTip _toolTip = new ToolTip();

        public WinFormsControlDriver(Control control)
        {
            _control = control;
        }


        public bool Visible
        {
            get { return _control.Visible; }
            set { _control.Visible = value; }
        }

        public bool Enabled
        {
            get { return _control.Enabled; }
            set { _control.Enabled = value; }
        }


        public void Focus()
        {
            _control.Focus();
        }

        public Color BackColor
        {
            get { return _control.BackColor; }
            set { _control.BackColor = value; }
        }


        public string GetKey()
        {
            if (_control.Parent != null)
            {
                return _control.Parent.GetType().FullName + "/" + _control.GetType().FullName + "/" + _control.Name;
            }
            else
            {
                return _control.GetType().FullName + "/" + _control.Name;
            }
        }


        public void OnLostFocus(Action action)
        {
            _control.LostFocus += delegate { action(); };
        }


        public void Click()
        {
            FireEvent(_control, "Click");
        }

        public void OnHover(Action action)
        {
            throw new NotImplementedException();
        }

        public static void FireEvent(object control, string eventName, params object[] args)
        {
            MethodInfo minfo =
                control.GetType().GetMethod("On" + eventName,
                                            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            ParameterInfo[] param = minfo.GetParameters();
            Type parameterType = param[0].ParameterType;
            minfo.Invoke(control, new[] { Activator.CreateInstance(parameterType) });
        }

        public void Click(object control)
        {
            FireEvent(control, "Click");            
        }


        public void FireLostFocus()
        {
            FireEvent(_control, "LostFocus");
        }


        public bool IsFocused
        {
            get { return _control.Focused; }
        }


        public object Control
        {
            get { return _control; }
        }

        public string Text
        {
            get { return _control.Text; }
        }

        public string ToolTipText
        {
            get { return _toolTip.GetToolTip(_control); }
            set { _toolTip.SetToolTip(_control, value); }
        }
    }
}